class Solution {
public:
    int minFallingPathSum(vector<vector<int>>& matrix) {
        int n = matrix.size();
        // dp[i][j] 表示：到 [i, j] 位置处，此时下降路径最小和
        // 初始化，保证填表正确，初始化成INT_MAX是为了不影响第1列和最后1列的比较大小
        vector<vector<int>> dp(n+1, vector<int>(n+2, INT_MAX)); // 多开一行两列
        for(int i = 0; i < n+2; ++i) // 这里初始化成0是为了不影响第一行的值
        {
            dp[0][i] = 0;
        }
 
        for(int i = 1; i <= n; ++i)
        {
            for(int j = 1; j <= n; ++j)
            {
                dp[i][j] = matrix[i-1][j-1] + min(min(dp[i-1][j], dp[i-1][j-1]), dp[i-1][j+1]);
            }
        }
 
        int ret = INT_MAX;
        for(int i = 1; i <= n; ++i)
        {
            ret = min(dp[n][i], ret);
        }
        return ret;
    }
};